package com.ourcraft.informationcollectionsystem.service.province.formQuery;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.query.MPJQueryWrapper;
import com.ourcraft.informationcollectionsystem.entity.City;
import com.ourcraft.informationcollectionsystem.entity.Company;
import com.ourcraft.informationcollectionsystem.entity.DataReportForm;
import com.ourcraft.informationcollectionsystem.entity.DTO.DataReportFormDTO;
import com.ourcraft.informationcollectionsystem.entity.InvestigationPeriod;
import com.ourcraft.informationcollectionsystem.mapper.CityMapper;
import com.ourcraft.informationcollectionsystem.mapper.CompanyMapper;
import com.ourcraft.informationcollectionsystem.mapper.DataReportFormMapper;
import com.ourcraft.informationcollectionsystem.mapper.InvestigationPeriodMapper;
import com.ourcraft.informationcollectionsystem.utils.ExportAndSendExcel;
import com.ourcraft.informationcollectionsystem.utils.LowerCamelToLowerUnderscore;
import com.ourcraft.informationcollectionsystem.utils.statusCode.DataReportFormStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.*;
import java.sql.Date;

@Service
public class FormQueryServiceImpl implements FormQueryService{
    @Autowired
    private DataReportFormMapper dataReportFormMapper;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private CityMapper cityMapper;
    @Autowired
    private InvestigationPeriodMapper investigationPeriodMapper;

    @Override
    public List<DataReportForm> getRequiredFormList(JSONObject company, JSONObject investigationPeriod) {
        // 最后的系统中没用到，但还是保存下来吧
        var new_company = LowerCamelToLowerUnderscore.exec_json(company);
        var city_name = cityMapper.selectOne(
                        new QueryWrapper<City>().eq("user_id", new_company.getInteger("company_city")));
        new_company.put("company_city", city_name == null ? null : city_name.getCityName());

        var companyQueryWrapper = new QueryWrapper<Company>()
                .allEq((k,v) -> v != null && v != "", new_company).select("company_id");
        var companyResult = companyMapper.selectList(companyQueryWrapper);
        ArrayList<Integer> tmp_array_company = new ArrayList<>();
        companyResult.forEach(c -> tmp_array_company.add(c.getCompanyId()));

        var tmp_array_inv = getInvestigationPeriodIds(investigationPeriod);

        var formQueryWrapper = new QueryWrapper<DataReportForm>()
                .in("company_id", tmp_array_company)
                .in("investigation_id", tmp_array_inv);
        return dataReportFormMapper.selectList(formQueryWrapper);
    }

    private ArrayList<Integer> getInvestigationPeriodIds(JSONObject investigationPeriod){
        // 判断调查是否符合时间范围、所在月份和季度的条件
        var investigationPeriodQueryMapper = new QueryWrapper<InvestigationPeriod>()
                .select("investigation_id", "investigation_start_date", "investigation_length");
        var investigationPeriodResult =  investigationPeriodMapper.selectList(investigationPeriodQueryMapper);
        ArrayList<Integer> tmp_array_inv = new ArrayList<>();
        Date begin = investigationPeriod.getSqlDate("investigationBegin");
        Date end = investigationPeriod.getSqlDate("investigationEnd");
        Integer month = investigationPeriod.getInteger("investigationMonth");
        Integer quarter = investigationPeriod.getInteger("investigationQuarter");
        for(var inv: investigationPeriodResult){
            Date inv_begin = inv.getInvestigationStartDate();
            Date inv_end = new Date(inv_begin.getTime() + inv.getInvestigationLength() * 24 * 60 * 60 * 1000);
            int inv_month = inv_begin.getMonth() + 1;
            int inv_quarter = inv_begin.getMonth() / 3 + 1;
            if (((begin == null) || (begin.compareTo(inv_begin)) <= 0)
                    && ((end == null) || (end.compareTo(inv_end) >= 0))
                    && ((month == null) || (month == inv_month))
                    && ((quarter == null) || (quarter == inv_quarter))
            ){
                tmp_array_inv.add(inv.getInvestigationId());
            }
        }

        return tmp_array_inv;
    }

    @Override
    public ResponseEntity<Resource> exportCurrentFormList(JSONObject company, JSONObject investigationPeriod) {
        List<DataReportFormDTO> queriedData = getRequiredFormListJoin(company, investigationPeriod);
        var exportExcel = new ExportAndSendExcel(DataReportFormDTO.class);
        exportExcel.export(queriedData);

        return exportExcel.send();
    }

    @Override
    public List<DataReportFormDTO> getRequiredFormListJoin(JSONObject company, JSONObject investigationPeriod) {
        var simple_cond = LowerCamelToLowerUnderscore.exec_json(company.getJSONObject("simple"));
        var city_name = cityMapper.selectOne(
                new QueryWrapper<City>().eq("user_id", simple_cond.getInteger("companyCity")));
        simple_cond.put("company_city", city_name == null ? null : city_name.getCityName());

        var id = simple_cond.getInteger("company_id");
        var location = company.getObject("companyLocation", ArrayList.class);
        var nature = company.getObject("companyNature", ArrayList.class);
        var industry = company.getObject("companyIndustry", ArrayList.class);
        var chineseName = company.getString("companyChineseName");
        // 较为复杂的联表查询，t代表联表后形成的新表
        var joinWrapper = new MPJQueryWrapper<DataReportForm>()
                .selectAll(DataReportForm.class)
                .select("investigation_start_date", "investigation_length")
                .select("company_chinese_name")
                .leftJoin("InvestigationPeriod on InvestigationPeriod.investigation_id = t.investigation_id")
                .leftJoin("Company on Company.company_id = t.company_id")
                .allEq((k,v) -> !Objects.equals(k, "company_id") && v != null && v != "", simple_cond)
                .like(chineseName != null && !chineseName.isEmpty(), "company_chinese_name", chineseName)
                .in(location != null && !location.isEmpty(), "company_location", location)
                .in(nature != null && !nature.isEmpty(), "company_nature", nature)
                .in(industry != null && !industry.isEmpty(), "company_industry", industry)
                .eq(id != null, "t.company_id", id)
                .ne("form_examine_status", DataReportFormStatus.NOT_FILL.ordinal());
        var tmp_set_inv = new HashSet<>(getInvestigationPeriodIds(investigationPeriod));

        var result = dataReportFormMapper.selectJoinList(DataReportFormDTO.class, joinWrapper);
        // 调查期的时间判断难以用SQL实现，选择用Java筛选
        result.removeIf(e -> !tmp_set_inv.contains(e.getInvestigationId()));
        return result;
    }
}
